/*
** main.c for ktrace in /home/matt/Desktop/ktrace
** 
** Made by mathieu1 lornac
** Login   <lornac_a@epitech.net>
** 
** Started on  Thu Dec  9 12:52:15 2010 mathieu1 lornac
** Last update Tue Dec 21 20:31:53 2010 mathieu1 lornac
*/

#include "parse.h"

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/ktrace.h>
#include <unistd.h>

/*
 * File preparation before the ktrace call
 */
void		open_file(t_args *args)
{
  int		fd;
  
  if (!(args->pid && args->clear))
    {
      if ((fd = open(args->filename, args->open_flags, S_IRWXU)) < 0)
	{
	  printf("Cannot open destination file: %s\n", args->filename);
	  exit(1);
	}
      close(fd);
    }
}

/*
 * Prints the usage of the call ktrace and then exits
 * with the error code 1
 */
void		error_print(void)
{
  printf("usage: ktrace [-aCcdi] [-f trfile] [-g pgrp | -p pid] [-t trstr]\n");
  printf("ktrace [-adi] [-f trfile] [-t trstr] command\n");
  exit(1);
}

/*
 *Checking consistency of the specified options
 * For instance you cant specify a process id to trace and 
 * give an exec name to trace at the same time
 */
void		args_checks(t_args *args, int ac)
{
  if ((args->pid && ac) || (!args->pid && !ac))
    error_print();
}

/*
 * Modify the tr_points according to the clear mode specified
 */
void		args_modify(t_args *args)
{
  if (args->clear == 1) /*c option given */
    {
      if (args->pid)
	args->tr_ops |= KTROP_CLEAR;
      else
	args->tr_ops |= KTROP_CLEARFILE;
    }
  else if (args->clear == 2) /*C option given */
    {
      args->tr_ops = KTROP_CLEAR | KTRFLAG_DESCEND;
      args->tr_points |= KTRFAC_CSW;
    }
}

int		main(int ac, char **av)
{
  t_args	*args;

  args = parse_args(ac, av);
  if (args)
    {
      av += args->args_to_skip;
      ac -= args->args_to_skip;
      args_checks(args, ac);
      args_modify(args);
      open_file(args);
      if (!args->pid)
	{
	  if (ktrace(args->filename, args->tr_ops, args->tr_points,
		     getpid()) < 0)
	    {
	      printf("Cannot run ktrace on: %s\n", args->filename);
	      return 0;
	    }
	  execvp(av[0], &av[0]);
	  printf("Execvp call of: %s FAILED\n", args->filename);
	}
      else if (ktrace(args->filename, args->tr_ops, args->tr_points,
		      args->pid) < 0)
	{
	  printf("Cannot run ktrace on: %s\n", args->filename);
	  return 0;
	}
    }
  else
    error_print();
  return 0;
}
